﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using MyLib.Data;
using MyLib.Web.UI;

namespace MyLib.Web.Pages {
	/// <summary>
	/// 
	/// Action: 109
	/// </summary>
	public abstract class RolesPage : MyPage {
		/// <summary>
		/// 
		/// </summary>
		private const int DefaultApplicationId = 1;

		/// <summary>
		/// 
		/// </summary>
		protected int ApplicationId {
			get {
				var obj = ViewState["ApplicationId"];
				if (obj == null) {
					return DefaultApplicationId;
				} else {
					return (int)obj;
				}
			}
			set {
				ViewState["ApplicationId"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		protected void DoQuery() {
			var gridView = this.FindDescendantControl<MyGridView>("GridView1");

			gridView.PageIndex = 0;
			gridView.DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected bool IsDeletable() {
			var row = (System.Data.DataRowView)Page.GetDataItem();

			var roleName = row.Get<string>("displayName");

			return roleName != "administrators"; // User "admin" cannot be deleted.
		}

		/// <summary>
		/// 
		/// </summary>
		protected void DoCreateNewRole() {
			CheckAuthoriy(Context, 106);

			ViewState["EditRoleId"] = "0";

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="roleId"></param>
		protected void DoEditRole(string roleId) {
			CheckAuthoriy(Context, 108);

			if (roleId == null || roleId.Length == 0) {
				return;
			}

			ViewState["EditRoleId"] = roleId;

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="roleId"></param>
		protected void DoDeleteRole(string roleId) {
			CheckAuthoriy(Context, 107);

			if (roleId == null || roleId.Length == 0) {
				return;
			}

			var c = GetDbProvider<MyLib.Data.AuthorityProvider>().DeleteRole(ApplicationId, roleId);
			if (c == 0) {
				var r = GetDbProvider<MyLib.Data.AuthorityProvider>().FindRoleById(ApplicationId, roleId);
				var rn = r.Count == 0 ? "?" : r[0].IsDisplayNameNull ? "?" : r[0].DisplayName;

				Context.AddError(string.Format(Properties.Main.ErrorRoleNotDeleted, roleId));
			}

			DoQuery();

			if (ViewState.Get<string>("EditRoleId") == roleId) {
				ViewState["EditRoleId"] = null;

				this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleQuery(bool causesValidation, string validationGroup) {
			this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleCreateNew(bool causesValidation, string validationGroup) {
			Context.ExecuteSafely(DoCreateNewRole);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			// Add object datasources.
			var ds1 = new MyObjectDataSource(typeof(MyLib.Data.AuthorityProvider).AssemblyQualifiedName, "FindRoles");
			ds1.ID = "ObjectDataSource1";
			ds1.SelectCountMethod = "FindRolesCount";
			ds1.EnableCaching = false;
			ds1.EnablePaging = true;

			ds1.SelectParameters.Add("applicationId", System.Data.DbType.Int32, ApplicationId.ToString());
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "roleName",
				Type = TypeCode.String,
				Key = "DisplayNameToMatch"
			});
			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "description",
				Type = TypeCode.String,
				Key = "DescriptionToMatch"
			});

			var ds2 = new MyObjectDataSource(typeof(MyLib.Data.AuthorityProvider).AssemblyQualifiedName, "FindRoleById");
			ds2.UpdateMethod = "SaveRole";
			ds2.ID = "ObjectDataSource2";
			ds2.EnableCaching = false;
			ds2.EnablePaging = false;

			ds2.SelectParameters.Add("applicationId", System.Data.DbType.Int32, ApplicationId.ToString());
			ds2.SelectParameters.Add(new MyViewStateParameter {
				Name = "roleId",
				Type = TypeCode.String,
				Key = "EditRoleId"
			});

			ds2.UpdateParameters.Add("applicationId", TypeCode.String, ApplicationId.ToString()); 
			ds2.UpdateParameters.Add("roleId", TypeCode.String, "");
			ds2.UpdateParameters.Add("displayName", TypeCode.String, "");
			ds2.UpdateParameters.Add("description", TypeCode.String, "");
			ds2.UpdateParameters.Add("actions", TypeCode.String, "");

			var ds3 = new MyObjectDataSource();
			ds3.ID = "ObjectDataSource3";
			ds3.GettingView += new EventHandler<MyObjectDataSourceGettingViewEventArgs>(OnRoleActionsGettingView);

			Controls.Add(ds1);
			Controls.Add(ds2);
			Controls.Add(ds3);

			// Assign event handlers.
			var formView1 = this.FindDescendantControl<MyFormView>("FormView1");
			formView1.DataSourceID = ds2.ID;

			var gridView1 = this.FindDescendantControl<MyGridView>("GridView1");
			gridView1.DataSourceID = ds1.ID;
			gridView1.AllowPaging = true;

			formView1.Saved += new EventHandler<MyFormViewSavedEventArgs>(OnFormView1Saved);
			formView1.Cancelled += new EventHandler<MyFormViewCommandEventArgs>(OnFormView1Cancelled);

			gridView1.RowCommand += new GridViewCommandEventHandler(OnGridView1RowCommand);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnRoleActionsGettingView(object sender, MyObjectDataSourceGettingViewEventArgs e) {
			e.View = new System.Data.DataView(GetAvailableActions(), null, "actionId", System.Data.DataViewRowState.CurrentRows);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected virtual ActionTable GetAvailableActions() {
			return GetDbProvider<AuthorityProvider>().FindActions();
		} // end of GetAvailableActions.

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);

			this.Title = Properties.Main.TitleRoles;

			if (!IsPostBack) {
				this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

				Context.ExecuteSafely(DoQuery);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="source"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		protected override bool OnBubbleEvent(object source, EventArgs args) {
			bool causesValidation = false;
			string validationGroup = string.Empty;

			if (args is CommandEventArgs) {
				IButtonControl commandSource = source as IButtonControl;
				if (commandSource != null) {
					causesValidation = commandSource.CausesValidation;
					validationGroup = commandSource.ValidationGroup;
				}

				var cargs = (CommandEventArgs)args;

				if (string.Equals(cargs.CommandName, "Query", StringComparison.OrdinalIgnoreCase)) {
					HandleQuery(causesValidation, validationGroup);
					return true;
				} else if (string.Equals(cargs.CommandName, "CreateNew", StringComparison.OrdinalIgnoreCase)) {
					HandleCreateNew(causesValidation, validationGroup);
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Saved(object sender, MyFormViewSavedEventArgs e) {
			ViewState["EditRoleId"] = "";

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Cancelled(object sender, MyFormViewCommandEventArgs e) {
			ViewState["EditRoleId"] = "";
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnGridView1RowCommand(object sender, GridViewCommandEventArgs e) {
			var arg = (string)e.CommandArgument;

			var userId = arg;

			Action act;
			switch (e.CommandName) {
				case "EditRole":
					act = () => DoEditRole(userId);
					break;
				case "DeleteRole":
					act = () => DoDeleteRole(userId);
					break;
				default:
					return;
			}

			Context.ExecuteSafely(act);
		}

	} // end of CodePage.
}
